﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using olierFrm.DataBase.FrameWork.Plugin;
using olierFrm.DataBase.FrameWork.DataDictornary;
using olierFrm.GeneralCache;

namespace olierFrm.DataBase.FrameWork.StdQuery
{
    public class StdQuerySQL : DefinedSQL
    {
        public WF_SmartQuery StdQuery
        {
            get;
            private set;
        }
        //private List<WF_SmartQueryParams> _StdQueryParams;

        public List<WF_SmartQueryParams> StdQueryParams
        {
            get;
            private set;
        }
        public List<WF_SmartQueryChecks> StdQueryChecks { get; private set; }

        public const string StdQueryCachePrefix = "StdQuery=";
        public const string StdQueryParamCachePrefix = "StdQueryParam=";
        public const string StdQueryCheckCachePrefix = "StdQueryCheck=";

        public StdQuerySQL(string SqlID)
        {

            //StackTrace st = new StackTrace();
            //st.GetFrame(1);
            //st.GetFrame(1).GetMethod().ReflectedType
            this.SqlID = SqlID;
            string CacheKey = StdQueryCachePrefix + SqlID;
            if (!Cache.KeyExists(CacheKey))
            {
                var stdquery = (from s in this.DBEntity.WF_SmartQuery where s.QueryName == SqlID select s).ToList();
                if (!stdquery.Any())
                    throw new FrameWorkError()
                    {
                        SqlID = this.SqlID,
                        ErrorObject = "StdQuery",
                        ErrorType = "执行查询时",
                        Summary = "StdQuery未定义"
                    };
                StdQuery = stdquery.First();
                Cache.Add(CacheKey, StdQuery);
            }
            else
            {
                StdQuery = (WF_SmartQuery)Cache.Get(CacheKey);
            }
            this.ObjectSQL.Add(new ObjectSQL() { Idx = 0, SqlID = SqlID, SQLText = StdQuery.SQL });

            string CacheParamKey = StdQueryParamCachePrefix + SqlID;
            if (!Cache.KeyExists(CacheParamKey))
            {
                StdQueryParams = (from p in this.DBEntity.WF_SmartQueryParams where p.QueryName == this.SqlID orderby p.ParamID select p).ToList();
                //if (StdQueryParams.Any())
                //{
                Cache.Add(CacheParamKey, StdQueryParams);
                //}
            }
            else
            {
                StdQueryParams = (List<WF_SmartQueryParams>)Cache.Get(CacheParamKey);
            }

            string CacheCheckKey = StdQueryCheckCachePrefix + SqlID;
            if (!Cache.KeyExists(CacheCheckKey))
            {
                StdQueryChecks = (from p in this.DBEntity.WF_SmartQueryChecks where p.QueryName == this.SqlID orderby p.Idx select p).ToList();
                Cache.Add(CacheCheckKey, StdQueryChecks);
            }
            else
            {
                StdQueryChecks = (List<WF_SmartQueryChecks>)Cache.Get(CacheCheckKey);
            }
            if (StdQueryParams != null)
                foreach (var s in StdQueryParams)
                {
                    this.ObjectSQLParam.Add(new ObjectSQLParam() { ParamName = s.ParamName, Idx = s.ParamID, ParamType = s.ParamType, Repeated = false });
                }
        }

        private bool Check()
        {
            if (StdQueryChecks == null) return true;

            foreach (var b in StdQueryChecks)
            {
                if (!b.Enabled) continue;

                if (b.ValidateType.ToUpper().Equals("REQUIRED"))
                {
                    var param = FindParamByName(b.ParamToValidate);
                    if (param.ParamValue.ToString().Equals(string.Empty))
                    {
                        throw new FrameWorkError()
                        {
                            SqlID = this.SqlID,
                            ErrorObject = "StdQuery",
                            ErrorType = "StdQuery检查：REQUIRED",
                            Summary = b.Summary
                        };
                    }
                }
                else if (b.ValidateType.ToUpper().Equals("QUERY"))
                {
                    var param = FindParamByName(b.ParamToValidate);
                    if (param.ParamValue == null) continue;

                    if (SqlHelper.ExecuteQuery(b.SQL, ObjectSQLParam.Where(oo => !oo.Repeated).ToList(), "QUERY").Rows.Count == 0)
                    {
                        throw new FrameWorkError()
                        {
                            SqlID = this.SqlID,
                            ErrorObject = "StdQuery",
                            ErrorType = "StdQuery检查：QUERY",
                            Summary = b.Summary,
                            Param = param.ParamName
                        };
                    }
                }
                else if (b.ValidateType.ToUpper().Equals("SQL"))
                {
                    var param = FindParamByName(b.ParamToValidate);
                    if (param.ParamValue == null) continue;

                    if (SqlHelper.ExecuteQuery(b.SQL, ObjectSQLParam.Where(oo => !oo.Repeated).ToList(), "SQL").Rows[0]["ResultCode"].ToString() != "0")
                    {
                        throw new FrameWorkError()
                        {
                            SqlID = this.SqlID,
                            ErrorObject = "StdQuery",
                            ErrorType = "StdQuery检查：SQL",
                            Summary = b.Summary,
                            Param = param.ParamName
                        };
                    }
                }
                else if (b.ValidateType.ToUpper().Equals("COMPARETO"))
                {
                    if (FindParamByName(b.ParamToCompare).ParamValue.Equals(FindParamByName(b.ParamToValidate).ParamValue))
                    {
                        throw new FrameWorkError()
                        {
                            SqlID = this.SqlID,
                            ErrorObject = "Business",
                            ErrorType = "Business检查：COMPARETO",
                            Summary = b.Summary + "，" + b.ParamToCompare + "<>" + b.ParamToValidate
                        };
                    }
                }
            }
            return true;
        }

        public DataTable ExecuteSumSQL()
        {
            try
            {
                if (StdQuery.SumSQL != null && StdQuery.SumSQL.Length != 0)
                    return this.SqlHelper.ExecuteQuery(StdQuery.SumSQL, this.ObjectSQLParam, this.SqlID, true);
            }
            catch (Exception ex)
            {
                throw new FrameWorkError() { SqlID = this.SqlID, ErrorObject = "StdQuerySum", ErrorType = "执行合计查询时", Summary = ex.Message };
            }
            return null;
        }

        //public DataTable ExecuteSQL()
        //{
        //    if (!Check())
        //    {
        //        return null;
        //    }
        //    try
        //    {
        //        //if (_StdQuery.ReplaceStrings == null || _StdQuery.ReplaceStrings.Length < 3)
        //        //    return SqlHelper.ExecuteQuery(_StdQuery.SQL, this.ObjectSQLParam, this.SqlID);

        //        //List<string> rs = _StdQuery.ReplaceStrings.Trim().Split(';').ToList();
        //        //rs.Remove("");
        //        //foreach (var r in rs)
        //        //{
        //        //    var rsf = r.Split('=');
        //        //    if (rsf[0].Contains("Column_"))
        //        //    {
        //        //        var columnValue = _StdQuery.GetType().GetProperty(rsf[1]).GetValue(_StdQuery, null);
        //        //        if (columnValue != null)
        //        //        {
        //        //            _StdQuery.SQL = _StdQuery.SQL.Replac e(rsf[0], columnValue.ToString());
        //        //        }
        //        //        continue;
        //        //    }
        //        //    var fv = from ff in this.ObjectSQLParam where ff.ParamName == rsf[1] select ff;
        //        //    if (fv.Any() )
        //        //    {
        //        //        if (fv.First().ParamValue == null)
        //        //            throw new FrmObjectError() { SqlID = this.SqlID, ErrorObject = "StdQuery", ErrorType = "将参数的值替换SQL时", Summary = "参数值为空" };
        //        //        _StdQuery.SQL = _StdQuery.SQL.Replace(rsf[0], fv.First().ParamValue.ToString());
        //        //    }
        //        //    else
        //        //    {
        //        //        throw new FrmObjectError() { SqlID = this.SqlID, ErrorObject = "StdQuery", ErrorType = "将参数的值替换SQL时", Summary = "参数值没有定义" };
        //        //    }
        //        //}
        //        var dt = this.SqlHelper.ExecuteQuery(StdQuery.SQL, this.ObjectSQLParam, this.SqlID);
        //        //DataDictionary.BindCaptionToDataTable(dt);

        //        return dt;
        //    }
        //    catch (Exception ex)
        //    {
        //        throw new FrameWorkError() { SqlID = this.SqlID, ErrorObject = "StdQuery", ErrorType = "执行查询时", Summary = "StdQuery：" + SqlID + "，" + ex.Message };
        //    }
        //}

        //public List<T> ExecuteSQL<T>() where T : class ,new()
        //{
        //    return this.SqlHelper.ExecuteQuery<T>(StdQuery.SQL, this.ObjectSQLParam);
        //}

        public DataTable AutoPagingExecuteSQL(int pageIndex, int pageRowCount)
        {
            var sqls = "";
            try
            {
                new ParseSQL(StdQuery.SQL, pageIndex, pageRowCount, out sqls);
                return this.SqlHelper.ExecuteQuery(sqls, this.ObjectSQLParam, this.SqlID, true);
            }
            catch (Exception ex)
            {
                throw new FrameWorkError() { SqlID = this.SqlID, ErrorObject = "StdQuery", ErrorType = "执行查询时", Summary = "StdQuery：" + SqlID + "，AutoPaging，" + ex.Message };
            }
        }

        public DataTable ExecuteSQL(int start = 0, int max = 0)
        {
            if (!Check())
            {
                return null;
            }
            try
            {
                return this.SqlHelper.ExecuteQuery(StdQuery.SQL, this.ObjectSQLParam, this.SqlID, true, start, max);
            }
            catch (Exception ex)
            {
                throw new FrameWorkError() { SqlID = this.SqlID, ErrorObject = "StdQuery", ErrorType = "执行查询时", Summary = "StdQuery：" + SqlID + "，" + ex.Message };
            }
        }
    }
}
